package com.sservice.web.controller.admin;

import com.sservice.common.Constants;
import com.sservice.common.LadingBillConstants;
import com.sservice.common.PrintContract;
import com.sservice.common.SameUrlData;
import com.sservice.urp.dao.IComDao;
import com.sservice.urp.dao.IDepDao;
import com.sservice.model.dao.IStoreDao;
import com.sservice.model.dao.OrderPaperMapper;
import com.sservice.model.vo.LadingBillVo;
import com.sservice.model.vo.LadingOrderVo;
import com.sservice.urp.entity.*;
import com.sservice.urp.vo.UserVo;
import com.sservice.service.service.*;
import com.sservice.base.entity.dto.BaseResult;
import com.sservice.base.entity.dto.ListResult;
import com.sservice.base.entity.dto.Pagination;
import com.sservice.web.log.Action;
import com.sservice.web.utils.PdfUtils;
import com.lowagie.text.DocumentException;
import com.sservice.web.common.Utils;
import com.sservice.model.entity.*;
import freemarker.template.TemplateException;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/admin/ladingBill")
public class LadingBillController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ILadingBillService service;
    @Autowired
    private ILadingOrderService loService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderPaperService orderPaperService;
    @Autowired
    private PurchaseOrderBillService pobService;
    @Autowired
    private OrderPaperMapper orderPaperMapper;
    @Autowired
    private ILadingOrderService ladingOrderervice;
    @Autowired
    private IOfferService offerService;
    @Autowired
    private IStoreService storeService;
    @Autowired
    private IComDao comMapper;
    @Autowired
    private IDepDao depMapper;
    @Autowired
    private IStoreDao storeMapper;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private ILadingBillLogService lblService;
    @Autowired
    private IClienteleService clienteleService;
    @Autowired
    private ISysLogService sysLogService;
    @Autowired
    private ExportService exportService;

    @ResponseBody
    @RequestMapping(value = "/save-paper", method = RequestMethod.POST)
    public BaseResult savePaper(OrderPaper op, HttpSession session, HttpServletRequest request) {
        User user = (User) session.getAttribute(Constants.USER);
        op.setOrderType("2");
        OrderPaper op_res = orderPaperMapper.selectByOrderIdAndOrderType(op);
        int res = 0;
        if (op_res == null) {
            op.setUserId(String.valueOf(user.getId()));
            op.setOrderType("2"); //
            sysLogService.log("保存提单", request, Integer.valueOf(op.getOrderId()), Action.ladingBillType);
            res = orderPaperService.insertSelective(op);
        } else {
            op_res.setUserId(String.valueOf(user.getId()));
            op_res.setPaper(op.getPaper());
            if (op.getPath() != null) {
                sysLogService.log("保存上传提单：" + op.getPath(), request, Integer.valueOf(op_res.getOrderId()), Action.ladingBillType);
            }
            if (op.getSingle() != null) {
                sysLogService.log("保存单签提单：" + op.getSingle(), request, Integer.valueOf(op_res.getOrderId()), Action.ladingBillType);
            }
            if (op.getCouple() != null) {
                sysLogService.log("保存双签提单：" + op.getCouple(), request, Integer.valueOf(op_res.getOrderId()), Action.ladingBillType);
            }
            op_res.setPath(op.getPath());
            op_res.setType(op.getType());
            op_res.setSingle(op.getSingle());
            op_res.setSignatureStatus(op.getSignatureStatus());
            op_res.setCouple(op.getCouple());
            res = orderPaperService.updateByPrimaryKeySelective(op_res);
            return new BaseResult(true, res);
        }
        return new BaseResult(true, res);
    }

    @RequestMapping(value = "/back/{id}-{clientleName}.pdf")
    public OutputStream backtoPdf(PurchaseOrder order, String id, String clientName, HttpSession session, HttpServletResponse response) throws DocumentException, TemplateException, IOException {
        OrderPaper op = new OrderPaper();
        op.setOrderId(String.valueOf(order.getId()));
        op.setOrderType("2");
        String paperTmp = "paper/print-test.ftl";
        OrderPaper op1 = orderPaperMapper.selectByOrderIdAndOrderType(op);
        ClassPathResource resource = new ClassPathResource(paperTmp);
        Map<Object, Object> o = new HashMap<Object, Object>();
        String body = new String(op1.getPaper());
        o.put("body", body);
        String path_ = resource.getURL().toString().replace(paperTmp, "");
        return PdfUtils.generateToServletOutputStream(path_.replace(
                "file:" + (!Constants.isDebug ? "" : "/"), ""),
                paperTmp,
                resource.getURL().toString().replace(paperTmp, ""),
                o,
                response);
    }

    @RequestMapping(value = "/pdf.pdf")
    public OutputStream pdf(HttpServletResponse response) throws IOException, TemplateException, DocumentException {
        String paperTmp = "paper/print-test.ftl";
        ClassPathResource resource = new ClassPathResource(paperTmp);
        String path_ = resource.getURL().toString().replace(paperTmp, "");
        Map<Object, Object> o = new HashMap<Object, Object>();
        o.put("body", "");
        return PdfUtils.generateToServletOutputStream(path_.replace(
                "file:" + (!Constants.isDebug ? "" : "/"), ""),
                paperTmp,
                resource.getURL().toString().replace(paperTmp, ""),
                o,
                response);
    }

    /**
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public BaseResult<Object> get(LadingBill arg, HttpSession session) {
        LadingBill service_res = service.selectByPrimaryKey(arg.getId());
        Map map = new HashMap();
        map.put("ladingBill", service_res);
        List<LadingOrder> lo = ladingOrderervice.selectByLadingId(arg.getId().toString());
        map.put("ladingBillDetail", lo);
        BaseResult res = new BaseResult(true, map);
        return res;
    }

    /***
     * @param arg
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/clear/{id}", method = RequestMethod.GET)
    public BaseResult<Object> clear(LadingBillVo arg, HttpSession session, HttpServletRequest request) {
        UserVo user = (UserVo) session.getAttribute(Constants.USER);
        Object service_res = service.clear(arg, user);
        sysLogService.log("清零", request, arg.getId(), Action.ladingBillType);
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /***
     * 替换批号
     * @param arg
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/replace/{id}", method = RequestMethod.POST)
    public BaseResult<Object> replace(LadingOrder arg, HttpSession session, HttpServletRequest request) {
        Object service_res = service.replace(arg);
        if (service_res instanceof String) {
            return new BaseResult(false, String.valueOf(service_res), 403);
        }
        sysLogService.log("替换批号", request, arg.getId(), Action.ladingBillType);

        BaseResult res = new BaseResult(true, service_res);
        return res;
    }


    /***
     * 未付款发货
     * @param arg
     * @param session
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/createUnPaied", method = RequestMethod.POST)
    public BaseResult<Object> createUnPaied(LadingBillVo arg, HttpSession session) {
        UserVo user = (UserVo) session.getAttribute(Constants.USER);
        arg.setUserId(String.valueOf(user.getId()));
        arg.setApplierType("0");
        arg.setCheckStatus("1");
        arg.setChecker(user.getUserName());
        arg.setCheckTime(new Date());
        Object service_res = service.create(arg, false);
        Boolean isManger = false;
        for (Role role : user.getRoles()) {
            if (String.valueOf(role.getId()).equals(Constants.SUPER_MANAGER_ROLE_ID)) { /// 超级管理员账户判断
                isManger = true;
            }
        }
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /**
     * 审核通过
     *
     * @param arg
     * @param session
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/allow", method = RequestMethod.POST)
    public BaseResult<Object> allow(LadingBillVo arg, HttpSession session, HttpServletRequest request) {
        UserVo user = (UserVo) session.getAttribute(Constants.USER);
        LadingBillVo lb = new LadingBillVo();
        lb.setUserId(String.valueOf(user.getId()));
        lb.setChecker(user.getUserName());
        lb.setCheckTime(new Date());
        lb.setStoreId(arg.getStoreId());
        lb.setStoreName(arg.getStoreName());
        lb.setId(arg.getId());
        lb.setExpireTime(arg.getExpireTime());
        lb.setDriver(arg.getDriver());
        lb.setDriverPhone(arg.getDriverPhone());
        lb.setOrderIds(arg.getOrderIds());
        lb.setBillIds(arg.getBillIds());
        lb.setBatchNum(arg.getBatchNum());
        lb.setReason(arg.getReason());
        Object service_res = service.allow(lb, false);
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        sysLogService.log("审核通过:" + arg.getReason(), request, Integer.valueOf(arg.getId()), Action.ladingBillType);

        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /**
     * refuse
     *
     * @param arg
     * @return
     */
    @RequestMapping(value = "/refuse", method = RequestMethod.POST)
    @ResponseBody
    @SameUrlData
    public BaseResult<Object> refuse(LadingBillVo arg, HttpServletRequest request) {
        Object service_res = service.refuse(arg);
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        sysLogService.log("审核拒绝：" + arg.getReason(), request, Integer.valueOf(arg.getId()), Action.ladingBillType);

        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /***
     * 发货
     * @param arg
     * @param session
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public BaseResult<Object> create(LadingBillVo arg, HttpSession session, HttpServletRequest request) {
        UserVo user = (UserVo) session.getAttribute(Constants.USER);
        arg.setUserId(String.valueOf(user.getId()));
        arg.setChecker(user.getUserName());
        arg.setCheckTime(new Date());
        arg.setApplierType("0");
        arg.setCheckStatus("1");
        String flag = "0";
        List<Permission> list = user.getPermissions();
        for (int i = 0; i < list.size(); i++) {
            Permission p = list.get(i);
            if (p.getId() == 42) {
                flag = "1";
            }
        }
        Object service_res = service.send(arg, flag);
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        sysLogService.log("发货,数量：" + arg.getNumberThisTime(), request, (Integer) service_res, Action.ladingBillType);

        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /**
     * 打印提单
     *
     * @param arg
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getPaper/{id}", method = RequestMethod.GET)
    public BaseResult<Object> print(LadingBill arg, HttpSession session) {
        LadingBill po = service.selectByPrimaryKey(arg.getId());
        if ("1".equals(po.getCheckStatus())) {
            OrderPaper op = new OrderPaper();
            op.setOrderType("2"); // 提货单
            op.setOrderId(String.valueOf(arg.getId()));
            OrderPaper pop = orderPaperMapper.selectByOrderIdAndOrderType(op);
            if (pop != null) {
                pop.setPaper_(new String(pop.getPaper()));
                return new BaseResult(true, pop);
            }
        }
        User user = (User) session.getAttribute(Constants.USER);
        if (user.getId() == 1) {
            return new BaseResult(false, "超级管理员不能保存合同", 403);
        }
        Com com = comMapper.selectByPrimaryKey(user.getComid());
        Dep dep = depMapper.selectByPrimaryKey(user.getDepid());

        Dep d = new Dep();
        d.setComid(String.valueOf(user.getComid()));
        d.setName("物流运营部");

        Dep dep1 = depMapper.queryByDepNameAndComId(d);
        if (dep1 != null) {
            dep = dep1; // 取物流部
        }
        Map<String, Object> map = new HashedMap();
        map.put("number", po.getNumberThisTime());
        map.put("type", po.getType());
        map.put("numberBig", PrintContract.changeUnit(po.getNumberThisTime().doubleValue())); // 数量大写
        Clientele clientele = clienteleService.selectByPrimaryKey(Integer.valueOf(po.getClienteleId()));
        map.put("buyer", po.getClienteleName()); // 需方
//        map.put("email", com.ge()); //需方邮箱
        map.put("no", po.getNo());
        map.put("time_place", new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " 上海");
        map.put("goodsName", po.getGoodsName());  //
        map.put("qualityRequire", po.getQualityRequire()); //质量标准
        map.put("qualitySpec", po.getQuality()); //品质规格
        map.put("storeName", po.getStoreName());
        Store store = storeMapper.selectByPrimaryKey(Integer.valueOf(po.getStoreId()));
        map.put("shortName", store.getShortName());
        map.put("carId", po.getCarId());

        map.put("driver", po.getDriver());
        map.put("IDCard", po.getDriverPhone()); // 司机身份证号
        map.put("expireTime", po.getExpireTime());
        map.put("comAddress", clientele.getAddress());
        map.put("comTel", clientele.getTel());
        map.put("comFax", clientele.getFax());
        map.put("comBank", clientele.getBank());
        map.put("comBankAccount", clientele.getBankAccount());
        map.put("buyerAddress", com.getAddress());
        map.put("provider", com.getName());
        map.put("buyerTel", com.getTel());
        map.put("storeFax", store.getFax());
        map.put("storeFee", store.getFee()); // 仓储费用
        map.put("buyerFax", com.getFax());
        map.put("depTel", dep.getTel());
        map.put("depFax", dep.getFax());
        List<LadingOrder> list = loService.selectByLadingId(String.valueOf(po.getId()));
        map.put("list", list);
        if ("1".equals(po.getType()) && po.getStoreName().equals("张家港保税区长江国际港务有限公司")) {
            PurchaseOrderBill pob = pobService.selectByPrimaryKey(Integer.valueOf(list.get(0).getBillId()));
            map.put("batchNumber", pob.getNumber());
        }
        return new BaseResult(true, map);

    }

    /**
     * @param arg
     * @return
     */
    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
    public BaseResult<Integer> delete(LadingBill arg, HttpSession session, HttpServletRequest request) {
        UserVo user = (UserVo) session.getAttribute(Constants.USER);
        boolean flag = false;
        List<Permission> list = user.getPermissions();
        for (int i = 0; i < list.size(); i++) {
            Permission p = list.get(i);
            if (p.getId() == 136) {
                flag = true;
            }
        }
        if (!flag) {
            return new BaseResult(false, "无删除操作权限!", 403);
        }
        Object service_res = service.deleteWithAuth(arg, flag);
        if (service_res instanceof String) {
            return new BaseResult(false, String.valueOf(service_res), 403);
        }
        sysLogService.log("删除", request, (Integer) arg.getId(), Action.ladingBillType);

        return new BaseResult(true, String.valueOf(service_res));
    }

    /**
     * @param arg
     * @return
     */
    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public BaseResult<Integer> update(LadingBill arg) {
        arg.setCheckStatus(null); // 禁止直接update审核
        int service_res = service.updateByPrimaryKeySelective(arg);
        BaseResult<Integer> res = new BaseResult<Integer>(true, service_res);
        return res;
    }
//    @ResponseBody
//    @SameUrlData
//    @RequestMapping(value = "/allow", method = RequestMethod.POST)
//    public BaseResult<Integer> allow(LadingBill arg,HttpServletRequest request) {
////        arg.setCheckStatus(null); // 禁止直接update审核
//        LadingBill lb  = new LadingBill();
//        lb.setCheckStatus(arg.getCheckStatus());
//        lb.setId(arg.getId());
//        if(lb.getCheckStatus()=="1"){
//            OrderPaper op = new OrderPaper();
//            op.setOrderId(String.valueOf(arg.getId()));
//            op.setOrderType("2");
//            OrderPaper op1 = orderPaperMapper.selectByOrderIdAndOrderType(op);
//            if (op1 == null) {
//                return new BaseResult(false, "请先编辑保存合同!", 403);
//            }else if(op1.getPaper()==null){
//                return new BaseResult(false, "请先编辑保存合同!", 403);
//            }
//            sysLogService.log("审核通过", request , (Integer) lb.getId(), Action.ladingBillType);
//        }
//        int service_res = service.updateByPrimaryKeySelective(lb);
//        BaseResult<Integer> res = new BaseResult<Integer>(true, service_res);
//        return res;
//    }

    /***
     * 录入实体数目
     * @param arg
     * @param session
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/batchUpdateLadingBillActual", method = RequestMethod.POST)
    public BaseResult<Object> batchUpdateLadingBillActual(LadingOrderVo arg, HttpSession session, HttpServletRequest request) {
        User user = (User) session.getAttribute(Constants.USER);
        Object obj = service.batchUpdateLadingBillActual2(arg, String.valueOf(user.getId()));
        if (obj instanceof Integer) {
            sysLogService.log("录入实提数", request, (Integer) obj, Action.ladingBillType);
            return new BaseResult(true, obj);
        } else {
            return new BaseResult(false, obj.toString(), 403);
        }
    }

    @ResponseBody
    @RequestMapping(value = "/update_labing_bill_actual", method = RequestMethod.POST)
    public BaseResult<Object> update_labing_bill_actual(LadingOrder arg, HttpSession session) {
        User user = (User) session.getAttribute(Constants.USER);
        // arg.setActual(Arith.add(arg.getActual(), se_res.getActual()));
        Object obj = service.update_labing_bill_actual(arg);
        if (obj instanceof Integer) {
            int obj_ = Integer.valueOf(obj.toString());
            LadingOrder se_res = ladingOrderervice.selectByPrimaryKey(arg.getId());
            lblService.insertLog(String.valueOf(user.getId()), arg.getId().toString(), LadingBillConstants.OPERATE_ADD_ACTUAL_NUMBER, arg.getActual().toString());
            return new BaseResult(true, obj_);
        } else {
            return new BaseResult(false, obj.toString(), 403);
        }
    }

    /***
     * 分页查询
     * @param arg
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/query", method = RequestMethod.GET)
    public ListResult query(LadingBillVo arg, HttpSession session, boolean isExport) {

        UserVo user = (UserVo) session.getAttribute(Constants.USER);
        if (user == null) {
            return new ListResult(false, "未登录!", 401);
        }
        arg.setBusinessId(String.valueOf(user.getId())); // 设置业务ID
        Boolean isManger = false;
        for (Role role : user.getRoles()) {
            if (String.valueOf(role.getId()).equals(Constants.SUPER_MANAGER_ROLE_ID)) { /// 超级管理员账户判断
                isManger = true;
            }
        }
        if (!isManger) { //运营账户判断判断
            arg.setReason(String.valueOf(user.getId())); //
        }

        Goods g = new Goods();
        g.setOperatorId(String.valueOf(user.getId()));
        if (!isManger && (goodsService.isOperator(g) == 0)) {
            return new ListResult(false, "非运营或超级管理员角色账号，无权访问!", 403);
        }
        if (isExport) {
            arg.setPage(0);
            arg.setSize(Integer.MAX_VALUE);
            List<LadingBill> list_order = service.queryByPage(arg);
            return new ListResult(true, list_order);
        }
        List<LadingBillVo> list = service.combineQueryByPage(arg);
        int total = service.queryCount(arg);
        Pagination page = new Pagination(arg.getPage(), total, arg.getSize());
        ListResult res = new ListResult(true, list);
        res.setPage(page);
        return res;
    }


    /***
     * 查询发票
     * @param arg
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/queryPaper", method = RequestMethod.GET)
    public ListResult queryPaper(LadingBillVo arg, HttpSession session) {

        UserVo user = (UserVo) session.getAttribute(Constants.USER);
        if (user == null) {
            return new ListResult(false, "未登录!", 401);
        }
        List<LadingBill> list = service.queryByPage(arg);
        int total = service.queryCount(arg);
        Pagination page = new Pagination(arg.getPage(), total, arg.getSize());
        ListResult res = new ListResult(true, list);
        res.setPage(page);
        return res;
    }

    /**
     * 导出提单功能
     *
     * @param arg
     * @param session
     * @return
     */
    @SameUrlData
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public OutputStream export(LadingBillVo arg, HttpSession session, HttpServletResponse response, HttpServletRequest request) throws IOException {
        ListResult lr = query(arg, session, true);
        List<LadingBill> list = (List<LadingBill>) lr.getList();
        ServletOutputStream outputStream = response.getOutputStream();
        response.setContentType("application/binary;charset=" + "UTF-8");
        String fileName = Utils.processFileName(request, "提单Excel");
        response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");// 组装附件名称和格式
        response.setCharacterEncoding("UTF-8");
        String hql = "提单"; // sheet 名称
        List<Map> lm = new ArrayList<Map>();
        for (int i = 0; i < list.size(); i++) {
            Map map = new LinkedHashMap();
            LadingBill ov = list.get(i);
            map.put("提单编号", ov.getNo());
            map.put("车号(收货公司)", ov.getCarId());
            map.put("产品名称", ov.getGoodsName());
            map.put("单价", ov.getPrice());
            map.put("金额", ov.getPrice().multiply(ov.getNumberThisTime()));
            map.put("提单类型", "0".equals(ov.getType()) ? "车号" : ("1".equals(ov.getType()) ? "转货权" : "介绍信"));
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
            map.put("提单有效期", sdf1.format(ov.getExpireTime()));
            map.put("提单数量", ov.getNumberThisTime());
            map.put("实提数量", ov.getActual());
            map.put("提单仓库", ov.getStoreName());
            map.put("客户名称", ov.getClienteleName());
            map.put("操作员", ov.getChecker());
            lm.add(map);
        }
        return exportService.exportExcel(hql, lm, outputStream);
    }

}
